package com.xtm.exercise.utils.easyexcel.model;


import com.one.common.utils.CheckFormatUtil;
import com.one.common.utils.DataCheckUtil;
import com.one.common.utils.easyexcel.annotation.*;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class EasyExcelImportModel {
    private Logger logger = LoggerFactory.getLogger(getClass());
    public String checkFieldIsNull(){
        Field[] fields = this.getClass().getDeclaredFields();
        StringBuffer errInfo = new StringBuffer();
        if(!ObjectUtils.isEmpty(fields)){
            for (Field field : fields) {
                NotNull notNullAnn = field.getAnnotation(NotNull.class);
                if(notNullAnn != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(ObjectUtils.isEmpty(retVal)){
                            errInfo.append(notNullAnn.message() + ",");
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                SpecialTextLength specialTextLength = field.getAnnotation(SpecialTextLength.class);
                if(specialTextLength != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(!CheckFormatUtil.checkSpecialTextLength(retVal.toString() , specialTextLength.maxLength() , 0 , "", new ArrayList<>())){
                                errInfo.append(specialTextLength.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                MaxLength maxLength = field.getAnnotation(MaxLength.class);
                if(maxLength != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            int[] lenArr = maxLength.maxLength();
                            Boolean lenErr = true;
                            for (int len : lenArr){
                                if(retVal.toString().length() == len){
                                    lenErr = false;
                                }
                            }

                            if(lenErr){
                                errInfo.append(maxLength.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                IdNumber idNumber = field.getAnnotation(IdNumber.class);
                if(idNumber != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(!DataCheckUtil.checkIdentityNumber(retVal.toString())){
                                errInfo.append(idNumber.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                PhoneNumber phoneNumber = field.getAnnotation(PhoneNumber.class);
                if(phoneNumber != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(!DataCheckUtil.checkPhoneNumber(retVal.toString())){
                                errInfo.append(phoneNumber.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                ShortNumber shortNumber = field.getAnnotation(ShortNumber.class);
                if(shortNumber != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(!DataCheckUtil.checkShortNumber(retVal.toString())){
                                errInfo.append(shortNumber.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                DateTimeValidate dateTimeValidate = field.getAnnotation(DateTimeValidate.class);
                if(dateTimeValidate != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(retVal instanceof Date){
                                Date retDate = (Date) retVal;
                                if(new SimpleDateFormat("yyyy-MM-dd").format(retDate).equalsIgnoreCase("1970-01-01")){
                                    errInfo.append(dateTimeValidate.message() + ",");
                                }
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                UseNumber useNumber = field.getAnnotation(UseNumber.class);
                if(useNumber != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(retVal instanceof BigDecimal){
                                BigDecimal numbers = (BigDecimal) retVal;
                                try{
                                    BigInteger bi = numbers.toBigIntegerExact();
                                    field.setAccessible(true);
                                    field.set(this , new BigDecimal(bi.intValue()));
                                    if(!DataCheckUtil.checkUseNumber(bi.intValue() + "")){
                                        errInfo.append(useNumber.message() + ",");
                                    }
                                }catch (Exception e){
                                    errInfo.append(useNumber.message() + ",");
                                }

                            }
                        }

                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                FloatNumber floatNumber = field.getAnnotation(FloatNumber.class);
                if(floatNumber != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if(!DataCheckUtil.checkMoney(retVal.toString())){
                                errInfo.append(floatNumber.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                FourDigitFloatNumber fourDigitFloatNumber = field.getAnnotation(FourDigitFloatNumber.class);
                if(fourDigitFloatNumber != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal)){
                            if (!DataCheckUtil.checkFourDigitNumber(retVal.toString())) {
                                errInfo.append(fourDigitFloatNumber.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

                BigDecimalValidate bigDecimalValidate = field.getAnnotation(BigDecimalValidate.class);
                if(bigDecimalValidate != null){
                    try {
                        Method getMethod = this.getClass().getMethod("get" + field.getName().substring(0 , 1).toUpperCase() + field.getName().substring(1));
                        Object retVal = getMethod.invoke(this);
                        if(!ObjectUtils.isEmpty(retVal) && retVal instanceof BigDecimal){
                            BigDecimal bd = (BigDecimal)retVal;
                            if(Math.subtractExact(bd.longValue() , Integer.MAX_VALUE * -1) == 0L){
                                errInfo.append(bigDecimalValidate.message() + ",");
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (IllegalAccessException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    } catch (InvocationTargetException e) {
                        logger.error(ExceptionUtils.getFullStackTrace(e));
                    }
                }

            }
        }

        return errInfo.toString();
    }
}
